<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    ## 作用域（重点）

    - 什么是作用域，就是一个变量可以生效的范围
    - 变量不是在所有地方都可以使用的，而这个变量的使用范围就是作用域
    ### 全局作用域
    - 全局作用域是最大的作用域
    - 在全局作用域中定义的变量可以在任何地方使用
    - 页面打开的时候，浏览器会自动给我们生成一个全局作用域 `window`
    - 这个作用域会一直存在，直到页面关闭就销毁了

    <script>
        // var a=10;//全局作用域
    </script>

    ### 局部作用域

    - 局部作用域就是在全局作用域下面有开辟出来的一个相对小一些的作用域
    - 在局部作用域中定义的变量只能在这个局部作用域内部使用
    - **在 `JS` 中只有函数能生成一个局部作用域，别的都不行**
    - 每一个函数，都是一个局部作用域
    <script>
        // console.log(a);//全局
        // function fn(){
        //     var b=20;
        //     console.log(b);//20 b拥有的局部的作用域,在函数内部正常使用的
        // }
        // fn();
        // console.log(b);//Uncaught ReferenceError: b is not defined
    </script>

    <!-- 总结:函数是半透明的,看得见外面,但是看不到里面 -->

    3.特殊情况:理解为bug
    如果函数内部声明的变量,声明的时候没有添加var关键字,函数内部声明的变量视为全局变量
    <script>
        // 相当于var a=100;
        // function fn(){
        //     a=100;
        //     console.log(a);//100
        // }

        // fn()
        // console.log(a);//100

        // function fn1(){
        //     b=200;
        // }
        // fn1()
        // console.log(b);//200
    </script>
    案例:
    // 第一题：
    <script>
    // var a = 1;//全局变量
    // function fn(a) {
    //     // var a=1;按照预解析,参数的相当于函数的内部的变量.
    //     console.log(a);//1
    //     a = 2;//局部变量
    //     console.log(a);//2
    // }
    // fn(a);
    // console.log(a);//1
    </script>

    <script>
        // var a = 1;
        // function fn() {
        //     console.log(a);//1
        //     a = 2;//全局变量
        //     console.log(a);//2
        // }
        // fn();
        // console.log(a);//2
    </script>

### 赋值规则
- 当你想给一个变量赋值的时候，那么就先要找到这个变量，在给他赋值
- 变量赋值规则：
  - 先在自己作用域内部查找，有就直接赋值
  - 没有就去上一级作用域内部查找，有就直接赋值
  - 还没有再去上一级作用域查找，有就直接赋值
  - 如果一直找到全局作用域都没有，那么就把这个变量定义为全局变量，再给他赋值
    <script>
        // function fn(){
        //     var a=b=3;//b=3 =>var a=b;
        //     console.log(a,b);//(3,3)
        // }
        // fn();
        // console.log(b);//3
        // console.log(a);//报错,is not defined
    </script>

    作用域链
    有了作用域之后哦,变量有了使用范围,也就有了规则
    变量的使用规则,访问规则,赋值规则

    1.访问规则
    当我想要获取一个变量的值的时候,我们管这个行为叫做访问
    <script>
        // var a=10;
        // console.log(a);
    </script>

    作用域链:
    获取变量的规则： 

    - 首先，在自己的作用域内部查找，如果有，就直接拿来使用
    - 如果没有，就去上一级作用域查找，如果有，就拿来使用
    - 如果没有，就继续去上一级作用域查找，依次类推
    - 如果一直到全局作用域都没有这个变量，那么就会直接报错（该变量 is not defined）
    <script>
        var a=10;
        // function fn(){
        //     var a=99;
        //     function fn1(){
        //         var  a=1000;
        //         console.log(a);//1000
        //     }
        //     fn1()
        // }
        // fn()
    </script>

    <script>
        function fn(){
            console.log(c);//Uncaught ReferenceError: c is not defined
            c=2;
            console.log(c);//2
        }
        fn();
        console.log(c);//2
    </script>
</body>
</html>